import axios from "axios";
import { ElMessage } from 'element-plus';
import router from '../router'; // 导入路由实例
import { useUserStore } from '../stores/user'; // 导入用户 store

const _commen_util = {
  // 默认Failure
  defaultFailure: (message, code, url) => {
    // 当拦截器处理了跳转逻辑后，不再重复弹出错误消息
    if (message !== '请重新登录') {
      ElMessage.error(message || '操作失败');
    }
    console.warn(`请求地址：${url}, 状态码：${code}, 错误信息:${message}`);
  },
  // 默认Err
  defaultErr: (err) => {
    console.error(
      "Caught error in common_util:",
      err ? err.message : "Unknown error",
      err ? err.stack : "No stack trace available",
    );
  },
  // ------------------方法封装-------------------------------------------------------------------
  internalPost: function (
    url,
    data,
    header,
    params,
    success,
    failure,
    error = this.defaultErr,
  ) {
    const finalHeader = { ...header };
    if (!(data instanceof FormData)) {
      finalHeader["Content-Type"] = "application/json";
    }
    return new Promise((resolve, reject) => {
      axios
        .post(url, data, {
          headers: finalHeader,
          params: params,
        })
        .then(({ data }) => {
          if (data.code === 200) {
            success(data.data, data.total, data.msg);
            resolve(data.data, data.total, data.msg);
          } else {
            failure(data.msg, data.code, data.url);
            reject(new Error(data.msg));
          }
        })
        .catch((err) => {
          if (err.response && err.response.data && err.response.data.msg) {
            ElMessage.error(err.response.data.msg);
          } else {
            //ElMessage.error('网络请求失败，请检查您的网络连接或联系管理员');
          }
          error(err);
          reject(err);
        });
    });
  },

  post: function (url, data, params, success, failure = this.defaultFailure) {
    const isFormData = data instanceof FormData;
    const header = isFormData
      ? { Token: this.takeAccessToken()?.token || "" }
      : this.accessHeader();
    return this.internalPost(url, data, header, params, success, failure);
  },
  // Get重写
  internalGet: function (
    url,
    header,
    params,
    success,
    failure,
    error = this.defaultErr,
  ) {
    return new Promise((resolve, reject) => {
      axios
        .get(url, { headers: header, params: params })
        .then(({ data }) => {
          if (data.code === 200) {
            success(data.data, data.total, data.msg);
            resolve(data.data, data.total, data.msg);
          } else {
            failure(data.msg, data.code, data.url);
            reject(new Error(data.msg));
          }
        })
        .catch((err) => {
          if (err.response && err.response.data && err.response.data.msg) {
            ElMessage.error(err.response.data.msg);
          } else {
            //ElMessage.error('网络请求失败，请检查您的网络连接或联系管理员');
          }
          error(err);
          reject(err);
        });
    });
  },
  get: function (url, params, success, failure = this.defaultFailure) {
    return this.internalGet(url, this.accessHeader(), params, success, failure);
  },
  // Delete重写
  internalDelete: function (
    url,
    header,
    params,
    success,
    failure,
    error = this.defaultErr,
  ) {
    return new Promise((resolve, reject) => {
      axios
        .delete(url, { headers: header, params: params })
        .then(({ data }) => {
          if (data.code === 200) {
            success(data.data, data.total, data.msg);
            resolve(data.data, data.total, data.msg);
          } else {
            failure(data.msg, data.code, data.url);
            reject(new Error(data.msg));
          }
        })
        .catch((err) => {
          if (err.response && err.response.data && err.response.data.msg) {
            ElMessage.error(err.response.data.msg);
          } else {
           // ElMessage.error('网络请求失败，请检查您的网络连接或联系管理员');
          }
          error(err);
          reject(err);
        });
    });
  },
  delete: function (url, params, success, failure = this.defaultFailure) {
    return this.internalDelete(
      url,
      this.accessHeader(),
      params,
      success,
      failure,
    );
  },
  // put重写
  internalPut: function (
    url,
    data,
    header,
    params,
    success,
    failure,
    error = this.defaultErr,
  ) {
    return new Promise((resolve, reject) => {
      axios
        .put(url, data, { headers: header, params: params })
        .then(({ data }) => {
          if (data.code === 200) {
            success(data.data, data.total, data.msg);
            resolve(data.data, data.total, data.msg);
          } else {
            failure(data.msg, data.code, data.url);
            reject(new Error(data.msg));
          }
        })
        .catch((err) => {
          if (err.response && err.response.data && err.response.data.msg) {
            ElMessage.error(err.response.data.msg);
          } else {
            //ElMessage.error('网络请求失败，请检查您的网络连接或联系管理员');
          }
          error(err);
          reject(err);
        });
    });
  },
  put: function (url, data, params, success, failure = this.defaultFailure) {
    return this.internalPut(
      url,
      data,
      this.accessHeader(),
      params,
      success,
      failure,
    );
  },
  // Patch重写
  internalPatch: function (
    url,
    data,
    header,
    params,
    success,
    failure,
    error = this.defaultErr,
  ) {
    const finalHeader = { ...header };
    if (!(data instanceof FormData)) {
      finalHeader["Content-Type"] = "application/json";
    }
    return new Promise((resolve, reject) => {
      axios
        .patch(url, data, { headers: finalHeader, params: params })
        .then(({ data }) => {
          if (data.code === 200) {
            success(data.data, data.total, data.msg);
            resolve(data.data, data.total, data.msg);
          } else {
            failure(data.msg, data.code, data.url);
            reject(new Error(data.msg));
          }
        })
        .catch((err) => {
          if (err.response && err.response.data && err.response.data.msg) {
            ElMessage.error(err.response.data.msg);
          } else {
           // ElMessage.error('网络请求失败，请检查您的网络连接或联系管理员');
          }
          error(err);
          reject(err);
        });
    });
  },
  patch: function (url, data, params, success, failure = this.defaultFailure) {
    const isFormData = data instanceof FormData;
    const header = isFormData
      ? { Token: this.takeAccessToken()?.token || "" }
      : this.accessHeader();
    return this.internalPatch(url, data, header, params, success, failure);
  },

  // ... [其他方法如 postWithFile, patchWithFile, token操作等保持不变] ...

  // ----------------------------------------token操作-------------------------------
  takeAccessToken: () => {
    const str = sessionStorage.getItem("Authorization");
    if (!str) {
      return null;
    }
    const authObj = JSON.parse(str);
    return authObj;
  },
  storeAccessToken: (token) => {
    const authObj = {
      token: token,
    };
    const str = JSON.stringify(authObj);
    sessionStorage.setItem("Authorization", str);
  },
  deleteAccessToken: () => {
    sessionStorage.removeItem("Authorization");
  },
  accessHeader: function () {
    const token = this.takeAccessToken();
    return token
      ? {
        "Content-Type": "application/json",
        Token: token.token,
      }
      : { "Content-Type": "application/json" };
  },
};


// ======> 全局拦截器 <======

/**
 * 请求拦截器
 * - 检查非白名单请求的Token是否存在
 */
axios.interceptors.request.use(config => {
  // 定义不需要Token的API白名单
  const whitelist = ['/api/user/login', '/api/user/register'];

  // 检查请求的URL是否在白名单内
  const isWhitelisted = whitelist.some(url => config.url.endsWith(url));

  if (!isWhitelisted) {
    // 对于非白名单的请求，检查Token
    const token = _commen_util.takeAccessToken()?.token;
    if (!token) {
      ElMessage.warning('您的登录状态已失效，请重新登录！');
      const userStore = useUserStore();
      userStore.logout(); // 清理store和sessionStorage
      // 返回一个被拒绝的Promise，中断该次请求
      return Promise.reject(new Error('No token found'));
    }
  }

  // 请求正常，继续发送
  return config;
}, error => {
  return Promise.reject(error);
});


/**
 * 响应拦截器
 * - 检查后端返回的特定信息，如“请重新登录”
 */
axios.interceptors.response.use(response => {
  const data = response.data;
  // 检查后端是否明确告知需要重新登录
  if (data && data.msg === '请重新登录') {
    ElMessage.error('您的登录已过期或在其他地方登录，请重新登录！');
    const userStore = useUserStore();
    userStore.logout(); // 调用登出action，清理状态并跳转
    return Promise.reject(new Error('Login required'));
  }
  // 如果响应正常，直接返回
  return response;
}, error => {
  // 对响应错误做点什么
  // 比如，如果收到401 Unauthorized状态码，也执行登出逻辑
  if (error.response && error.response.status === 401) {
    ElMessage.error('认证失败，请重新登录！');
    const userStore = useUserStore();
    userStore.logout();
  }
  // 将错误继续抛出，让具体的catch块可以处理
  return Promise.reject(error);
});


export default _commen_util;